package game;

import java.awt.Point;

import org.w3c.dom.Element;

/**
 * <p>Implements the 8 Queen's Problem. The player is given eight queens and must place all eight queens on the board without 
 * threatening any other <tt>Queen</tt> already placed on the board.</p>
 * 
 * @author Nicole Waldrum
 * @date January 30. 2010
 * @version 1.0
 * 
 * @author Mark Kelly
 * @date February 20, 2010
 * @version 2.0
 * 
 * @author Trevor Bastian
 * @date March 29, 2010
 * @version 4.0
 *
 */
public class EightQueens extends GameType {
	private static final int QUEENS_FOR_WIN = 8;
	private static final Team QUEEN_COLOUR = Team.BLACK;

	/**
	 * <p>Creates a new instance of EightQueens.</p>
	 * 
	 * <p>After this constructor returns, {@code setGameState()} must be called before any other method is invoked.</p>
	 */
	public EightQueens() {
		super();
	}
	
	/**
	 * {@inheritDoc}
	 * 
	 * <p>In the case of the Eight Queens Problem, it must be noted that another <tt>Queen</tt> is on the board.</p>
	 */
	public void pieceMoved (GameState gs, Piece p, ChessBoard b) {
		if (hasWon(p.getTeam())) {
			state.stateChanged(state);
			state.notifyGameWon(p.getTeam());
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * <p>In the case of the Eight Queens Problem, an empty board is created.</p>
	 */
	@Override
	public void setupBoard() {
		state.setBoard(new ChessBoard(boardSize));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * <p>In the case of the Eight Queens Problem, eight queens must be on the board and not in each other's movement paths.</p>
	 */
	@Override
	public boolean hasWon(Team team) {
		return (state.getBoard().getPieceList(Queen.class, QUEEN_COLOUR).size() == EightQueens.QUEENS_FOR_WIN);
	}
	
	/**
	 * {@inheritDoc}
	 * 
	 * <p>In the case of the Eight Queens Problem, a <tt>Queen</tt> cannot be placed in the movement path of another <tt>Queen</tt>.</p>
	 */
	public boolean isValidMove(Piece piece, Point dest) {
		if (state.getBoard().hasPieceAt(dest))
			return false;
		
		// Can another Queen reach this location?
		for (Piece p : state.getBoard().getAllPieces()) {
			if (p.isValidMove(p, dest)) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean takeTurn(Point start, Point dest) {
		ChessBoard board = state.getBoard();
		Piece queen = new Queen(dest, QUEEN_COLOUR);
		if (isValidMove(queen, dest)) {
			board.movePiece(queen, dest);
			state.notifyPieceMoved(queen, board);
			return true;
		}
		return false;
	}

	@Override
	public void needPieceChoice(GameState gs) {
		// TODO Auto-generated method stub
		
	}

	public static EightQueens importFromXML (Element elem) {
		return new EightQueens();
	}
}
